#include "ThreadMangent.h"
#include "ThreadWrapper.h"   

#include <iostream>
#include <thread>   
#include <unordered_map>
#include <chrono>
#include <functional>
bool ThreadMangent::addTask(std::string taskname, std::function<void()> func, ThreadPriority priority)
{
        std::lock_guard<std::mutex> lock(m_mutex);
        // 检查是否已经存在同名线程
        if (threadMap.find(taskname) != threadMap.end())
        {
            std::cout << "Thread " << taskname << " already exists." << std::endl;
            return false;
        }

        try{
            // 使用 std::make_unique 创建一个新的 ThreadWrapper 实例
            std::unique_ptr<ThreadWrapper> newThread = std::make_unique<ThreadWrapper>();
            if (!newThread)
            {
                std::cout << "Failed to create new thread." << std::endl;
                return false;
            }
            if (taskname != "")
            {
                newThread->setName(taskname);    // 设置线程名
            }
            if(func != nullptr)
            {
                // 包装用户提供的 func 以匹配新的 setmain 签名
                // 注意：这个包装器本身不检查 stop_token，理想情况下 func 内部应该检查
                newThread->setmain([user_func = std::move(func)](const std::atomic<bool>& stop_token){
                    // 可以选择在这里检查 stop_token，但这可能不是 func 期望的行为
                    // if (stop_token.load(std::memory_order_acquire)) { return; }
                    user_func(); // 直接调用用户函数
                });
            }
            if (priority != ThreadPriority::NORMAL)
            {
#ifdef _WIN32  
                newThread->setPriority(_MapLinuxPriorityToWindows(priority));   // 设置线程优先级
#elif __linux__
                newThread->setPriority(static_cast<int>(priority));   // 设置线程优先级
#endif 
            }


            // 将新线程加入到 map 中
            threadMap[taskname] = std::move(newThread);
        }
        catch(const std::exception& e)
        {
            std::cerr << e.what() << '\n';
            return false;
        }

        return true;
}  
bool ThreadMangent::addTask(std::string taskname, ThreadPriority priority)
{
    return addTask(taskname,nullptr,priority);
}

bool ThreadMangent::addTasks(std::vector<std::string> tasknames, ThreadPriority priority)
{
    std::lock_guard<std::mutex> lock(m_mutex); 
    bool result = true; 
    for (auto taskname : tasknames)
    {
        result &= addTask(taskname,priority);
    }
    return result;
}    
bool ThreadMangent::addTasks(std::vector<std::pair<std::string, std::function<void()>>> tasknames, ThreadPriority priority)
{
    std::lock_guard<std::mutex> lock(m_mutex); 
    bool result = true; 
    for (auto taskname : tasknames)
    {
        result &= addTask(taskname.first,taskname.second,priority);
    }
    return result;
}
bool ThreadMangent::addTasks(std::map<std::string, std::function<void()>> tasknames, ThreadPriority priority){
    std::lock_guard<std::mutex> lock(m_mutex); 
    bool result = true; 
    for (auto taskname : tasknames)
    {
        result &= addTask(taskname.first,taskname.second,priority);
    }
    return result;
}
//    void addTask(std::string taskname, std::function<void()> func); 
bool ThreadMangent::setMain(std::string taskname, std::function<void()> func)
{
        std::lock_guard<std::mutex> lock(m_mutex);
        // 检查是否已经存在同名线程
        if (threadMap.find(taskname) == threadMap.end())
        {
            std::cout << "Thread " << taskname << " does not exist." << std::endl;
            return false;
        }
        // 检查线程是否已经在运行
        if(threadMap[taskname]->isRunning())
        {
            std::cout << "Thread " << taskname << " is running." << std::endl;
            return false;
        }   
        // 设置线程主函数 - 同样需要包装
        threadMap[taskname]->setmain([user_func = std::move(func)](const std::atomic<bool>& stop_token){
             // 注意：这个包装器本身不检查 stop_token，理想情况下 func 内部应该检查
             user_func(); // 直接调用用户函数
        }); 

        return true;
}
bool ThreadMangent::start(std::string threadName, bool lock)
{
    if (lock) {
        std::lock_guard<std::mutex> lock(m_mutex);
    }
    // 检查是否已经存在同名线程 
    if (threadMap.find(threadName) == threadMap.end())
    {
        std::cout << "Thread " << threadName << " does not exist." << std::endl;
        return false;
    }
    // 检查线程是否已经在运行
    if (threadMap[threadName]->isRunning())
    {
        std::cout << "Thread " << threadName << " is running." << std::endl;
        return false;
    }
    // 检查是否设置了线程主函数
    if (!threadMap[threadName]->hasMain())
    {
        std::cout << "Thread " << threadName << " has no main function." << std::endl;
        return false;
    }   
    // 启动线程
    threadMap[threadName]->start();
    return true;
}
bool ThreadMangent::startAll()
{
    std::lock_guard<std::mutex> lock(m_mutex);  // 锁定一次，适用于整个操作
    bool result = true; 
    for (auto& thread : threadMap)
    {
        result &= start(thread.first,false);
    }
    return result;
}
bool ThreadMangent::stop(std::string threadName, bool lock)
{
    if (lock) {
        std::lock_guard<std::mutex> lock(m_mutex);
    }
    // 检查是否已经存在同名线程 
    if (threadMap.find(threadName) == threadMap.end())
    {
        std::cout << "Thread " << threadName << " does not exist." << std::endl;
        return false;
    }
    // 检查线程是否已经在运行
    if (!threadMap[threadName]->isRunning())
    {
        std::cout << "Thread " << threadName << " is not running." << std::endl;
        return false;
    }
    // 停止线程 - 注意这里调用 stop(true) 即强制kill，根据需要调整
    threadMap[threadName]->stop(true);
    return true;
}
bool ThreadMangent::stopAll()
{
    std::lock_guard<std::mutex> lock(m_mutex);  // 锁定一次，适用于整个操作
    bool result = true; 
    for (auto& thread : threadMap)
    {
        result &= stop(thread.first,false);
    }
    return result;
}
bool ThreadMangent::join(std::string threadName, bool lock)
{
    if (lock) {
    std::lock_guard<std::mutex> lock(m_mutex);
    }
    // 检查是否已经存在同名线程 
    if (threadMap.find(threadName) == threadMap.end())
    {
        std::cout << "Thread " << threadName << " does not exist." << std::endl;
        return false;
    }
    // 检查线程是否已经在运行
    if (!threadMap[threadName]->isRunning())
    {
        std::cout << "Thread " << threadName << " is not running." << std::endl;
        return false;
    }
    if(!threadMap[threadName]->isJoinable())
    {
        std::cout << "Thread " << threadName << " is not joinable." << std::endl;
        return  false;
    }
    // 等待线程结束 - 使用新的 stop() (默认非 kill)
    threadMap[threadName]->stop();

    return  true;
}
bool ThreadMangent::joinAll()
{
    std::lock_guard<std::mutex> lock(m_mutex);  
    bool result = true; 
    for (auto& thread : threadMap)
    {
        result &= join(thread.first,false);
    }
    return result;
}

int ThreadMangent::getRunningThreadCount()const
{
    std::lock_guard<std::mutex> lock(m_mutex);  
    int count = 0;
    for (auto& thread : threadMap)
    {
        if(thread.second->isRunning())
        {
            count++;
        }
    }
    return count;
}
int ThreadMangent::getThreadCount()const
{
    std::lock_guard<std::mutex> lock(m_mutex); 
    return threadMap.size();
}
int ThreadMangent::checkThreads(ThreadAttribute attribute, std::string threadName)const
{
    std::lock_guard<std::mutex> lock(m_mutex); 
    if(threadName == "")
    {
        int count = 0;
        bool allcheck = false;
        switch (attribute)
        {
        case ThreadAttribute::ALL:
            allcheck = true; 
            [[fallthrough]];
        case ThreadAttribute::ThreadName:
            for (auto& thread : threadMap)
            {
                std::cout << thread.first << std::endl;
            }   
            if (!allcheck) {
            return threadMap.size();
            }
            [[fallthrough]];
        case ThreadAttribute::ThreadFunc:
            for (auto& thread : threadMap)
            {
                if(thread.second->hasMain())
                {
                    count++;
                }
                std::cout << thread.first << " : " << thread.second->hasMain() << std::endl;
            }
            if(!allcheck) {
                return count;
            }
            [[fallthrough]];
        case ThreadAttribute::ThreadRunning:
            for (auto& thread : threadMap)
            {
                if(thread.second->isRunning())
                {
                    count++;
                }
                std::cout << thread.first << " : " << thread.second->isRunning() << std::endl;
            }
            if(!allcheck) {
                return count;
            }
            [[fallthrough]];
        case ThreadAttribute::ThreadCount:
            std::cout << "Thread count : " << threadMap.size() << std::endl;
            break;
        default:
            std::cout << "Thread attribute error." << std::endl;
            break;
        }
    }
    else
    {
        if(threadMap.find(threadName) == threadMap.end())
        {
            std::cout << "Thread " << threadName << " does not exist." << std::endl;
            return -1;
        }       
        switch (attribute)
        {
        case ThreadAttribute::ALL:
            std::cout << threadName << std::endl;
            std::cout << threadName << " : " << threadMap.at(threadName)->hasMain() << std::endl;
            std::cout << threadName << " : " << threadMap.at(threadName)->isRunning() << std::endl;
            break;
        case ThreadAttribute::ThreadName:
            std::cout << threadName << std::endl;
            break;
        case ThreadAttribute::ThreadFunc:
            std::cout << threadName << " : " << threadMap.at(threadName)->hasMain() << std::endl;   
            break;
        case ThreadAttribute::ThreadRunning:
            std::cout << threadName << " : " << threadMap.at(threadName)->isRunning() << std::endl;
            break;
        default:
            std::cout << "Thread attribute error." << std::endl;
            break;
        }
    }

    return 0;
}   
#ifdef _WIN32
inline int ThreadMangent::_MapLinuxPriorityToWindows(ThreadPriority priority)const {
    // 定义 Windows 优先级范围
    const int WindowsMinPriority = 0;
    const int WindowsMaxPriority = 31;

    // 根据 Linux 优先级枚举值映射到 Windows 优先级
    switch (linuxPriority) {
        case ThreadPriority::HIGHEST:
            return WindowsMaxPriority;
        case ThreadPriority::VERY_HIGH:
            return WindowsMaxPriority - 5;  // 示例值，需要根据具体情况调整
        case ThreadPriority::HIGH:
            return WindowsMaxPriority - 10; // 示例值，需要根据具体情况调整
        case ThreadPriority::ABOVE_NORMAL:
            return WindowsMaxPriority / 2 + 5; // 示例值，需要根据具体情况调整
        case ThreadPriority::NORMAL:
            return WindowsMaxPriority / 2;
        case ThreadPriority::BELOW_NORMAL:
            return WindowsMaxPriority / 2 - 5; // 示例值，需要根据具体情况调整
        case ThreadPriority::LOW:
            return WindowsMaxPriority / 2 - 10; // 示例值，需要根据具体情况调整
        case ThreadPriority::VERY_LOW:
            return WindowsMinPriority + 5;  // 示例值，需要根据具体情况调整
        case ThreadPriority::LOWEST:
            return WindowsMinPriority;
        default:
            return WindowsMaxPriority / 2;  // 对于未知值，默认为普通优先级
    }
}
#endif 
